package com.tobeface.wechat.message.tracing;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.tobeface.modules.lang.Langs;
import com.tobeface.modules.lang.Requires;
import com.tobeface.wechat.message.WeChatMessage;
import com.tobeface.wechat.message.WeChatMessagePayloads;
import com.tobeface.wechat.message.WeChatMessageTracingService;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * @author loudyn
 */
public final class DefaultWeChatMessageTracingService implements WeChatMessageTracingService {

    private final CacheLoader<String, Integer> loader = new CacheLoader<String, Integer>() {
        @Override
        public Integer load(String key) throws Exception {
            return 0;
        }
    };

    private final LoadingCache<String, Integer> counters = CacheBuilder.newBuilder()
                                                                        .expireAfterWrite(30, TimeUnit.SECONDS)
                                                                        .build(loader);

    @Override
    public boolean isDuplicateMessage(WeChatMessage message) {

        Requires.notNull(message, "message must not be null!");
        try {

            if (!message.isEmptyPayloads()) {
                String msgId = getMessageId(message);
                return counters.get(msgId) > 0;
            }

            // empty payloads means just read, ignore it..
            return false;
        } catch (ExecutionException e) {
            throw Langs.impossiable();
        }
    }

    private String getMessageId(WeChatMessage message) {
        if (message.getPayloads().containsKey(WeChatMessagePayloads.MSGID_PAYLOAD)) {
            return (String) message.getPayloads().get(WeChatMessagePayloads.MSGID_PAYLOAD);
        }

        return String.format("%s-%s", message.getSender(), message.getCreateTime());
    }

    @Override
    public void tracingMessage(WeChatMessage message) {
        Requires.notNull(message, "message must not be null!");
        if (!message.isEmptyPayloads()) {
            String msgId = getMessageId(message);
            counters.put(msgId, 1);
        }
    }

    @Override
    public void untracingMessage(WeChatMessage message) {
        Requires.notNull(message, "message must not be null!");
        if (!message.isEmptyPayloads()) {
            String msgId = getMessageId(message);
            counters.put(msgId, 0);
        }
    }
}
